package com.example.shiro.demo.filter;

/**
 * <Description> <br>
 *
 * @author renweiping<br>
 * @version 1.0<br>
 * @taskId: <br>
 * @createDate 2019/10/15 12:34 <br>
 * @see com.example.shiro.demo.shiro <br>
 */
import java.io.IOException;
import java.util.Set;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.CollectionUtils;
import org.apache.shiro.util.StringUtils;
import org.apache.shiro.web.filter.authz.RolesAuthorizationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/***

 * @author renweiping
 * @description 通过角色验证权限
 * @date    2019/10/15

 */
public class ExtendRolesAuthorizationFilter extends RolesAuthorizationFilter{

    private static final Logger log = LoggerFactory.getLogger(ExtendRolesAuthorizationFilter.class);

    @Override
    public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {

        log.info(ExtendRolesAuthorizationFilter.class.toString());
        Subject subject = getSubject(request, response);
        String[] rolesArray = (String[]) mappedValue;

        if (rolesArray == null || rolesArray.length == 0) {
            //no roles specified, so nothing to check - allow access.
            return true;
        }
        //AbstractFilter
        Set<String> roles = CollectionUtils.asSet(rolesArray);

        boolean flag=false;
        for(String role: roles){
            if(subject.hasRole(role)){
                flag=true;
                break;
            }
        }
        return flag;
    }

    @Override
    public boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException{
        Subject subject = getSubject(request, response);
        // If the subject isn't identified, redirect to login URL
        if (subject.getPrincipal() == null) {
            saveRequestAndRedirectToLogin(request, response);
        } else {
            // If subject is known but not authorized, redirect to the unauthorized URL if there is one
            // If no unauthorized URL is specified, just return an unauthorized HTTP status code
            String unauthorizedUrl = getUnauthorizedUrl();
            //SHIRO-142 - ensure that redirect _or_ error code occurs - both cannot happen due to response commit:
            if (StringUtils.hasText(unauthorizedUrl)) {
                WebUtils.issueRedirect(request, response, unauthorizedUrl);
            } else {
                WebUtils.toHttp(response).sendError(HttpServletResponse.SC_UNAUTHORIZED);
            }
        }
        return false;
    }

}
